import express, { Request, Response } from 'express';
import { authenticateJWT } from '../middleware/authMiddleware';
import { DeviceManager } from '../device/DeviceManager';
import { AppDataSource } from '../config/database';
import { BranchAccount } from '../entity/BranchAccount';
import {DeviceGroupManager} from "../device/DeviceGroupManager";
import {Device} from "../entity/Device";
import {AccessToken} from "../entity/Accesstoken";
import { getStrategy } from '../brand/strategyFactory';
import { MideaMock } from '../brand/midea/MideaMock';
import { XiaomiMock } from '../brand/xiaomi/XiaomiMock';

const router = express.Router();
const dm = new DeviceManager();
const groupManager = new DeviceGroupManager();


// 定义统一响应格式
interface ApiResponse {
  status: 'success' | 'error';
  message?: string;
  data?: any;
  errors?: any[];
}
//
// // 处理跨域请求
// router.use((req: Request, res: Response, next: express.NextFunction) => {
//   res.header('Access-Control-Allow-Origin', '*');
//   res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
//   res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
//   next();
// });



/**
 * 获取设备列表（同步 + 查询）
 */
router.get('/getList', authenticateJWT, async (req, res) => {
  const userId = (req as any).user.userId;

  try {
    // 查询用户的第三方授权记录
    const repo = AppDataSource.getRepository(BranchAccount);
    const bindings = await repo.find({ where: { userId } });

    for (const { brand, token } of bindings) {
      try {
        await dm.syncDevices(userId, brand, token);
      } catch (err:any) {
        console.error(`[SYNC] Failed to sync devices for ${brand}:`, err.message);
        // 继续尝试下一个品牌
      }
    }

    const allDevices = await dm.getUserDevices(userId);

    const devices = allDevices.map(d => ({
      did: d.did,
      name: d.name,
      type: d.type,
      brand: d.brand,
      group: d.gid ?? null
    }));

    res.json({
      code: 200,
      data: { devices }
    });
  } catch (err: any) {
    console.error(`[DEVICE] getList failed:`, err.message);
    res.status(500).json({
      code: 500,
      message: 'Internal server error, failed to get device list'
    });
  }
});


// 创建分组
router.post('/createGroup', authenticateJWT, async (req, res) => {
  const userId = (req as any).user.userId;
  const { gname } = req.body;

  try {
    const group = await groupManager.createGroup(userId, gname);
    res.json({
      code: 200,
      message: '分组创建成功',
      data: { gid: group.gid, gname: group.gname }
    });
  } catch (err: any) {
    const msg = err.message;
    const code = msg.includes('已存在') ? 400 : msg.includes('最多') ? 409 : 400;
    res.status(code).json({ code, message: msg });
  }
});


// 设置设备分组
router.post('/setGroup', authenticateJWT, async (req, res) => {
  const userId = (req as any).user.userId;
  const { device_id, group_id } = req.body;

  try {
    const result = await groupManager.setGroup(userId, device_id, group_id ?? null);
    res.json({ code: 200, message: '分组设置成功', data: result });
  } catch (err: any) {
    res.status(400).json({ code: 400, message: err.message });
  }
});


// 删除分组
router.post('/deleteGroup', authenticateJWT, async (req, res) => {
  const userId = (req as any).user.userId;
  const { gid } = req.body;

  try {
    const count = await groupManager.deleteGroup(userId, gid);
    res.json({
      code: 200,
      message: '分组删除成功',
      data: { affected_devices: count }
    });
  } catch (err: any) {
    res.status(404).json({ code: 404, message: err.message });
  }
});


// 获取分组列表
router.get('/groups', authenticateJWT, async (req, res) => {
  const userId = (req as any).user.userId;

  try {
    const groups = await groupManager.getGroups(userId);
    res.json({ code: 200, data: groups });
  } catch (err: any) {
    res.status(500).json({ code: 500, message: err.message });
  }
});

// 全部设备状态获取
router.get('/status', authenticateJWT, async (req, res) => {
  const userId = (req as any).user.userId;

  try {
    const devices = await dm.getDevicesWithStatus(userId);
    res.json({
      code: 200,
      data: { devices }
    });
  } catch (err: any) {
    res.status(500).json({
      code: 500,
      message: '设备状态获取失败'
    });
  }
});



// // 获取美的设备列表API
// router.get('/midea/devices', authenticateJWT, async (req: Request, res: Response): Promise<void> => {
//   // 验证请求头
//   const accessToken = req.headers.authorization?.replace('Bearer ', '');
//   const clientId = req.headers.clientid as string;
//
//   if (!accessToken || !clientId) {
//     res.status(400).json({
//       status: 'error',
//       message: 'Missing required headers: Authorization or ClientId'
//     } as ApiResponse);
//     return;
//   }
//
//   try {
//     const userId = (req as any).user.userId;
//     const tokenRepo = AppDataSource.getRepository(accessToken);
//     const tokenRecord = await tokenRepo.findOne({
//       where: { token: accessToken, appId: clientId, userId }
//     });
//
//     if (!tokenRecord || tokenRecord.expiresAt < new Date()) {
//       res.status(401).json({
//         status: 'error',
//         code: 100,
//         message: 'access_token不存在或已过期'
//       } as ApiResponse);
//       return;
//     }
//
//     const deviceRepo = AppDataSource.getRepository(Device);
//     const devices = await deviceRepo.find({
//       where: { userId, brand: 'midea' },
//       select: ['did', 'name', 'type']
//     });
//
//     const response = {
//       reqId: 1,
//       applianceList: devices.map(device => ({
//         virtualId: device.did,
//         type: device.type,
//         name: device.name,
//         online: true
//       }))
//     };
//
//     res.json({
//       status: 'success',
//       data: response
//     } as ApiResponse);
//   } catch (err: any) {
//     res.status(500).json({
//       status: 'error',
//       message: err.message
//     } as ApiResponse);
//   }
// });
//
// // 获取小米设备列表API
// router.get('/xiaomi/devices', authenticateJWT, async (req: Request, res: Response): Promise<void> => {
//   // 验证请求头
//   const accessToken = req.headers['access_token'] as string;
//   const appId = req.headers['app_id'] as string;
//
//   if (!accessToken || !appId) {
//     res.status(400).json({
//       status: 'error',
//       message: 'Missing required headers: access_token or app_id'
//     } as ApiResponse);
//     return;
//   }
//
//   try {
//     const userId = (req as any).user.userId;
//     const tokenRepo = AppDataSource.getRepository(accessToken);
//     const tokenRecord = await tokenRepo.findOne({
//       where: { token: accessToken, appId, userId }
//     });
//
//     if (!tokenRecord || tokenRecord.expiresAt < new Date()) {
//       res.status(401).json({
//         status: 'error',
//         message: 'Invalid or expired access_token'
//       } as ApiResponse);
//       return;
//     }
//
//     const deviceRepo = AppDataSource.getRepository(Device);
//     const devices = await deviceRepo.find({
//       where: { userId, brand: 'xiaomi' },
//       select: ['did', 'name', 'type']
//     });
//
//     const response = {
//       devices: devices.map(device => ({
//         did: device.did,
//         name: device.name,
//         type: device.type,
//         online: true
//       }))
//     };
//
//     res.json({
//       status: 'success',
//       data: response
//     } as ApiResponse);
//   } catch (err: any) {
//     res.status(500).json({
//       status: 'error',
//       message: err.message
//     } as ApiResponse);
//   }
// });

// 获取美的设备列表API（移除JWT）
router.get('/midea/devices', async (req, res) => {
  // 验证请求头
  const accessToken = req.headers.authorization?.replace('Bearer ', '');
  const clientId = req.headers.clientid as string;

  // 获取请求参数中的 reqId（改为字符串类型）
  const reqId = req.query.reqId ? String(req.query.reqId) : "default-req-id";

  if (!accessToken || !clientId) {
    res.status(400).json({
      code: 400,
      message: '缺少必要请求头: Authorization 或 ClientId'
    });
    return;
  }

  try {
    // 通过accessToken获取用户ID（不再依赖JWT）
    const tokenRepo = AppDataSource.getRepository(AccessToken);
    const tokenRecord = await tokenRepo.findOne({
      where: { token: accessToken, appId: clientId }
    });

    if (!tokenRecord || tokenRecord.expiresAt < new Date()) {
      res.status(401).json({
        code: 401,
        message: 'access_token不存在或已过期'
      });
      return;
    }

    // 直接从token记录获取用户ID
    const userId = tokenRecord.userId;

    const deviceRepo = AppDataSource.getRepository(Device);
    const devices = await deviceRepo.find({
      where: { userId, brand: 'midea' },
      select: ['did', 'name', 'type']
    });

    const response = {
      reqId: reqId,
      applianceList: devices.map(device => ({
        virtualId: device.did,
        type: device.type,
        name: device.name,
        online: true
      }))
    };

    res.json({
      code: 200,
      data: response
    });
  } catch (err: any) {
    res.status(500).json({
      code: 500,
      message: `服务器错误: ${err.message}`
    });
  }
});

// 获取小米设备列表API（移除JWT）
router.get('/xiaomi/devices', async (req: Request, res: Response) => {
  // 验证请求头
  const accessToken = req.headers['access_token'] as string;
  const appId = req.headers['app_id'] as string;

  if (!accessToken || !appId) {
    res.status(400).json({
      code: 400,
      message: '缺少必要请求头: access_token 或 app_id'
    });
    return;
  }


  try {
    const tokenRepo = AppDataSource.getRepository(AccessToken);
    const tokenRecord = await tokenRepo.findOne({
      where: { token: accessToken, appId }
    });

    if (!tokenRecord || tokenRecord.expiresAt < new Date()) {
      res.status(401).json({
        code: 401,
        message: 'access_token无效或已过期'
      });
      return;
    }

    // 直接从token记录获取用户ID
    const userId = tokenRecord.userId;

    const deviceRepo = AppDataSource.getRepository(Device);
    const devices = await deviceRepo.find({
      where: { userId, brand: 'xiaomi' },
      select: ['did', 'name', 'type']
    });

    const response = {
      devices: devices.map(device => ({
        did: device.did,
        name: device.name,
        type: device.type,
        online: true
      }))
    };

    res.json({
      code: 200,
      data: response
    });
  } catch (err: any) {
    res.status(500).json({
      code: 500,
      message: `服务器错误: ${err.message}`
    });
  }
});

// 美的设备订阅
router.post('/midea/device/subscribe', async (req: Request, res: Response): Promise<void> => {
  const { reqId, applianceCode } = req.body;
  const accessToken = req.headers.authorization?.replace('Bearer ', '');
  const clientId = req.headers.clientid as string;

  if (!accessToken || !clientId) {
    res.status(400).json({ 
      reqId,
      code: 400,
      message: '缺少必要请求头: Authorization 或 ClientId' 
    });
    return;
  }

  try {
    // 验证access_token
    const tokenRepo = AppDataSource.getRepository(AccessToken);
    const tokenRecord = await tokenRepo.findOne({ 
      where: { token: accessToken, appId: clientId }
    });

    if (!tokenRecord || tokenRecord.expiresAt < new Date()) {
      res.status(401).json({ 
        reqId,
        code: 1006,
        message: '用户验证失败' 
      });
      return;
    }

    // 执行订阅
    const strategy = getStrategy('midea');
    await strategy.subscribeDevice(accessToken, applianceCode);

    res.json({ reqId, code: 200, message: '订阅成功' });
  } catch (err: any) {
    const code = err.message.includes('设备不存在') ? 1300 : 1006;
    res.status(code === 1300 ? 404 : 401).json({ 
      reqId,
      code,
      message: err.message 
    });
  }
});

// 美的设备取消订阅
router.post('/midea/device/subscribe/cancel', async (req: Request, res: Response): Promise<void> => {
  const { reqId, applianceCode } = req.body;
  const accessToken = req.headers.authorization?.replace('Bearer ', '');
  const clientId = req.headers.clientid as string;

  if (!accessToken || !clientId) {
    res.status(400).json({ 
      reqId,
      code: 400,
      message: '缺少必要请求头: Authorization 或 ClientId' 
    });
    return;
  }

  try {
    // 验证access_token
    const tokenRepo = AppDataSource.getRepository(AccessToken);
    const tokenRecord = await tokenRepo.findOne({ 
      where: { token: accessToken, appId: clientId }
    });

    if (!tokenRecord || tokenRecord.expiresAt < new Date()) {
      res.status(401).json({ 
        reqId,
        code: 1006,
        message: '用户验证失败' 
      });
      return;
    }

    // 执行取消订阅
    const strategy = getStrategy('midea');
    await strategy.revokeDeviceSubscription(tokenRecord.userId, applianceCode);

    res.json({ reqId, code: 200, message: '取消订阅成功' });
  } catch (err: any) {
    const code = err.message.includes('设备不存在') ? 1300 : 1006;
    res.status(code === 1300 ? 404 : 401).json({ 
      reqId,
      code,
      message: err.message 
    });
  }
});

// 小米设备订阅
router.post('/xiaomi/device/subscribe', async (req: Request, res: Response): Promise<void> => {
  const { did, 'receiver-url': receiverUrl } = req.body;
  const accessToken = req.headers.access_token as string;
  const appId = req.headers.app_id as string;

  if (!accessToken || !appId) {
    res.status(400).json({ 
      code: 400,
      message: '缺少必要请求头: access_token 或 app_id' 
    });
    return;
  }

  try {
    // 验证access_token
    const tokenRepo = AppDataSource.getRepository(AccessToken);
    const tokenRecord = await tokenRepo.findOne({ 
      where: { token: accessToken, appId }
    });

    if (!tokenRecord || tokenRecord.expiresAt < new Date()) {
      res.status(401).json({ 
        code: 903,
        message: '授权过期' 
      });
      return;
    }

    // 执行订阅
    const strategy = getStrategy('xiaomi');
    await strategy.subscribeDevice(accessToken, did);

    res.json({ code: 200, message: '订阅成功' });
  } catch (err: any) {
    const code = err.message.includes('设备不存在') ? 1 : 903;
    res.status(code === 1 ? 404 : 401).json({ 
      code,
      message: err.message 
    });
  }
});

// 小米设备取消订阅
router.post('/xiaomi/device/subscribe/cancel', async (req: Request, res: Response): Promise<void> => {
  const { did } = req.body;
  const accessToken = req.headers.access_token as string;
  const appId = req.headers.app_id as string;

  if (!accessToken || !appId) {
    res.status(400).json({ 
      code: 400,
      message: '缺少必要请求头: access_token 或 app_id' 
    });
    return;
  }

  try {
    // 验证access_token
    const tokenRepo = AppDataSource.getRepository(AccessToken);
    const tokenRecord = await tokenRepo.findOne({ 
      where: { token: accessToken, appId }
    });

    if (!tokenRecord || tokenRecord.expiresAt < new Date()) {
      res.status(401).json({ 
        code: 903,
        message: '授权过期' 
      });
      return;
    }

    // 执行取消订阅
    const strategy = getStrategy('xiaomi');
    await strategy.revokeDeviceSubscription(tokenRecord.userId, did);

    res.json({ code: 200, message: '取消订阅成功' });
  } catch (err: any) {
    const code = err.message.includes('设备不存在') ? 1 : 903;
    res.status(code === 1 ? 404 : 401).json({ 
      code,
      message: err.message 
    });
  }
});

// 美的设备控制路由
router.post('/midea/device/control', async (req, res) => {
  const { reqId, applianceId, control } = req.body;
  const accessToken = req.headers.authorization as string;
  const clientId = req.headers.clientid as string;

  try {
    const strategy = getStrategy('midea') as MideaMock;
    const result = await strategy.controlDevice(accessToken, reqId, applianceId, control);
    
    res.json({
      code: 200,
      ...result
    });
  } catch (err: any) {
    const codeMap: Record<string, number> = {
      '用户验证失败': 1006,
      '设备不存在': 1300,
      '参数非法': 1002
    };
    
    res.status(400).json({
      code: codeMap[err.message] || 400,
      message: err.message
    });
  }
});

// 小米设备控制路由
router.post('/xiaomi/device/control', async (req, res) => {
  const { did, control } = req.body;
  const accessToken = req.headers.access_token as string;
  const appId = req.headers.app_id as string;

  try {
    const strategy = getStrategy('xiaomi') as XiaomiMock;
    const result = await strategy.controlDevice(accessToken, did, control);
    
    res.json(result);
  } catch (err: any) {
    const codeMap: Record<string, number> = {
      '授权过期': 903,
      '设备不存在': 1,
      '属性不存在': 3,
      '属性值错误': 43
    };
    
    res.status(400).json({
      code: codeMap[err.message] || 400,
      message: err.message
    });
  }
});


export default router;

